<!--通用组件：文件上传-->
<template>
  <div style="width: 100%">
    <a-upload
      :file-list="fileList"
      :draggable="draggable"
      :accept="accept"
      :disabled="disabled"
      :limit="limit"
      :show-file-list="false"
      :show-link="false"
      :auto-upload="false"
      :show-cancel-button="false"
      @before-upload="beforeUpload"
      @change="onFileChange"
    >
      <template #upload-button>
        <div v-permission="[uploadPermission]" class="btn-upload">
          <icon-upload style="margin-right: 8px" />上传文件
        </div>
        <div v-if="accept" v-permission="[uploadPermission]" class="tips-box">
          提示：支持{{ accept }}文件格式
        </div>
        <div
          v-if="fileCheckFlg"
          v-permission="[uploadPermission]"
          class="check-box"
        >
          请上传文件
        </div>
      </template>
    </a-upload>
    <template v-for="item in fileList" :key="item.id || item.uid">
      <div class="file-item">
        <div class="left">
          <icon-file style="width: 24px; height: 24px; margin-right: 8px" />
          {{ item.name }}
        </div>
        <div class="right">
          <div v-if="showSize" class="size">{{ getSize(item) }}</div>
          <div class="status">
            <a-space>
              <span> 完成 </span>
              <icon-check-circle-fill
                :style="{ color: '#07bb06', fontSize: '16px' }"
              />
            </a-space>
          </div>
          <div :key="item.uid">
            <SecretLevelSelect
              v-model="item.secretLevel"
              :disabled="item.flg === '1'"
              :default-value="item.secretLevel"
              :secret-level="filterSecretLevel"
              style="width: 200px; margin-right: 16px"
              @change="(value) => updateSecretLevel(value, item.uid)"
            />
            <div v-if="item.checked" class="check-box">请选择</div>
          </div>
          <icon-delete
            v-permission="[delPermission]"
            class="del-btn"
            @click="removeFile(item)"
          />
        </div>
      </div>
    </template>
  </div>
</template>

<script setup lang="ts" name="FileUpload">
  import { ref, watch } from 'vue';
  import { FileItem, Message, Modal } from '@arco-design/web-vue';
  import SecretLevelSelect from '@/common/components/cac-components/secret-level-select/index.vue';

  const props = defineProps({
    fileLists: {
      type: Array,
      default: () => {
        return [];
      },
    },
    modelValue: {
      type: Array,
      default: () => {
        return [];
      },
    },
    uploadPermission: { type: String, default: '' },
    delPermission: { type: String, default: '' },
    // a-upload属性
    draggable: { type: Boolean, default: false },
    accept: { type: String, default: '' },
    disabled: { type: Boolean, default: false },
    fileRequired: { type: Boolean, default: true },
    secretRequired: { type: Boolean, default: true },
    filterSecretLevel: {
      type: Number || String,
      default: undefined,
    },
    limit: { type: Number, default: 0 },
    maxSize: { type: Number, default: null },
    showSize: { type: Boolean, default: false },
  });
  const fileList = ref<any[]>([]);
  const fileCheckFlg = ref(false);
  const emit = defineEmits(['update:fileLists', 'deleteFile']);
  watch(
    () => props.modelValue,
    (n: any) => {
      if (n) {
        fileList.value = [...n];
        fileList.value?.forEach((e: any) => {
          e.flg = '1';
          e.secretLevel = `${e.secretLevel}`;
        });
      }
    },
    {
      immediate: true,
      deep: true,
    }
  );
  const getSize = (item: any) => {
    let size = 0;
    if (item?.file) {
      size = item.file?.size;
    } else {
      size = item.size;
    }
    let temp;
    if (size < 1024) {
      return `${size} B`;
    }
    if (size < 1024 * 1024) {
      temp = size / 1024;
      temp = temp.toFixed(2);
      return `${temp} KB`;
    }
    if (size < 1024 * 1024 * 1024) {
      temp = size / (1024 * 1024);
      temp = temp.toFixed(2);
      return `${temp} MB`;
    }
    return '0 B';
  };
  const beforeUpload = (file: any): boolean | Promise<any> => {
    return new Promise((resolve, reject) => {
      const fileType = file?.name.split('.');
      const fileSize = file?.size || 0;
      if (!props?.accept) {
        resolve(true);
        return;
      }
      if (props?.accept.indexOf(fileType[fileType.length - 1]) > -1) {
        resolve(true);
      } else {
        Message.warning(`仅支持上传${props.accept}文件类型`);
        reject();
      }
      if (props.maxSize && fileSize > props.maxSize) {
        Message.warning(`文件大小超过${props.maxSize}！`);
        reject();
      }
    });
  };
  const onFileChange = (files: FileItem[], file: FileItem) => {
    file.status = 'uploading';
    files.forEach((e: any) => {
      e.flg = e.flg || '0';
    });
    fileList.value = files;
    if (props.fileRequired && fileList.value?.length === 0) {
      fileCheckFlg.value = true;
    } else {
      fileCheckFlg.value = false;
    }
    console.log(fileList.value, 'uploading');

    emit('update:fileLists', fileList.value);
  };
  const updateSecretLevel = (value: any, fileId: string) => {
    fileList.value?.forEach((e: any) => {
      if (e.uid === fileId) {
        e.secretLevel = value;
      }
      e.checked = false;
      if (props.secretRequired && !e.secretLevel) {
        e.checked = true;
      }
    });
  };

  const validate = () => {
    return new Promise((resolve, reject) => {
      if (props.fileRequired && props.secretRequired) {
        if (fileList.value?.length === 0) {
          fileCheckFlg.value = true;
          reject();
        } else if (checkSecret()) {
          reject();
        } else {
          resolve(true);
        }
      } else if (props.fileRequired) {
        if (fileList.value?.length === 0) {
          fileCheckFlg.value = true;
          reject();
        } else {
          resolve(true);
        }
      } else if (props.secretRequired) {
        if (checkSecret()) {
          reject();
        } else {
          resolve(true);
        }
      } else {
        resolve(true);
      }
    });
  };
  const checkSecret = () => {
    let flag = false;
    fileList.value?.forEach((e: any) => {
      if (props.secretRequired && !e.secretLevel) {
        e.checked = true;
        flag = true;
      }
    });
    return flag;
  };
  const removeFile = (file: any) => {
    if (file.flg === '1') {
      Modal.info({
        title: '提示',
        titleAlign: 'start',
        content: '删除后，数据将无法恢复，请确实是否删除',
        closable: true,
        modalClass: 'tips-modal',
        okText: '确认删除',
        hideCancel: false,
        cancelText: '取消',
        onOk: async () => {
          emit('deleteFile', file);
        },
        onCancel: () => {
          console.log('del cancle');
        },
      });
    } else {
      fileList.value?.forEach((e: any, i: any) => {
        if (e.uid) {
          if (e.uid === file.uid) {
            fileList.value.splice(i, 1);
          }
        } else if (e.id === file.id) {
          fileList.value.splice(i, 1);
        }
      });
    }
  };

  defineExpose({ validate });
</script>

<style lang="less" scoped>
  .btn-upload {
    width: 112px;
    height: 32px;
    background: #ffffff;
    border-radius: 3px 3px 3px 3px;
    border: 1px solid #d9dee7;
    padding: 5px 16px;
  }
  .tips-box {
    height: 20px;
    font-size: 14px;
    color: #828b9b;
    line-height: 20px;
    text-align: left;
    margin-top: 8px;
  }
  .check-box {
    min-height: 20px;
    color: rgb(var(--danger-6));
    font-size: 12px;
    line-height: 20px;
  }
  .file-item {
    margin-top: 8px;
    background: #f7f9fc;
    padding: 10px 8px;
    border-radius: 6px 6px 6px 6px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    .left {
      display: flex;
      align-items: center;
    }
    .right {
      display: flex;
      align-items: center;
      .status {
        font-size: 14px;
        color: #1e2228;
        margin-right: 30px;
      }
      .size {
        font-size: 14px;
        color: #1e2228;
        margin-right: 30px;
      }
      .del-btn {
        cursor: pointer;
      }
    }
  }
</style>
